﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DbSharp.Tools.DbConnectionBuilder.Core.Plugin;
using DbSharp.Tools.DbConnectionBuilder.Core;

namespace DbSharp.Tools.DbConnectionBuilder.UI
{
    partial class FormConnConfig : Form
    {
        #region Private memebers
        PluginProvider m_PluginProvider = new PluginProvider();
        IDbConnectionPlugin m_SelectedPlugin;
        int m_SelectedPluginIndex = -1;
        bool m_DbFileVersionMust;
        #endregion


        #region Private methods

        private void LoadDbPluginProviders()
        {
            var listSupportedPlugin = m_PluginProvider.GetSupportedDbPlugins();
            comboBoxDbPlugins.Items.Clear();
            foreach (var plugin in listSupportedPlugin)
            {
                comboBoxDbPlugins.Items.Add(plugin);
            }
        }
        
        private void InitUIByDbCredential(DbServerCredential credential)
        {
            //clear all input textbox
            textBoxDatabase.Text = string.Empty;
            textBoxDataSource.Text = string.Empty;
            textBoxPassword.Text = string.Empty;
            textBoxUserID.Text = string.Empty;
            textBoxServerPort.Text = string.Empty;
            comboBoxFileVersion.Items.Clear();
            comboBoxFileVersion.SelectedItem = null;

            //Database
            if (credential.DatabaseEnabled)
                textBoxDatabase.Text = credential.Database;
            textBoxDatabase.Enabled = credential.DatabaseEnabled;
            labelDatabase.Enabled = textBoxDatabase.Enabled;

            //ServerPort
            if (credential.ServerPortEnabled)
                textBoxServerPort.Text = credential.ServerPort;
            textBoxServerPort.Enabled = credential.ServerPortEnabled;
            labelServerPort.Enabled = textBoxServerPort.Enabled;

            //DataSource
            if (credential.DataSourceEnabled)
                textBoxDataSource.Text = credential.DataSource;
            textBoxDataSource.Enabled = credential.DataSourceEnabled;
            labelDataSource.Enabled = textBoxDataSource.Enabled;

            //UserId
            if (credential.UserIdEnabled)
                textBoxUserID.Text = credential.UserId;
            textBoxUserID.Enabled = credential.UserIdEnabled;
            labelUserID.Enabled = textBoxUserID.Enabled;

            //Password
            if (credential.PasswordEnabled)
                textBoxPassword.Text = credential.Password;
            textBoxPassword.Enabled = credential.PasswordEnabled;
            labelPassword.Enabled = textBoxPassword.Enabled;

            //OsInteAuth
            radioBtnOSAuth.Enabled = credential.OsInteAuthEnabled;
            if (radioBtnOSAuth.Enabled == false)
                radioBtnPasswordAuth.Checked = true;
            else
                radioBtnOSAuth.Checked = credential.OsInteAuth;

            //FileVersion 
            m_DbFileVersionMust = credential.DbFileVersionEnabled;
            if (credential.DbFileVersionEnabled)
            {
                foreach (var item in credential.ListCandidateDbFileVersionPair)
                {
                    comboBoxFileVersion.Items.Add(item);
                }
                if (credential.DbFileVersion != null)
                    comboBoxFileVersion.SelectedItem = credential.DbFileVersion;
            }
            labelFileVersion.Enabled = credential.DbFileVersionEnabled;
            comboBoxFileVersion.Enabled = credential.DbFileVersionEnabled;

            //AdditionalInfo
            label_AdditionalInfo.Text = credential.AdditionalInfo;

            //other parts
        }

        private DbServerCredential InitDbCredentialByUI()
        {
            DbServerCredential credential = new DbServerCredential();
            credential.Database = textBoxDatabase.Text;
            credential.DataSource = textBoxDataSource.Text;
            credential.UserId = textBoxUserID.Text;
            credential.Password = textBoxPassword.Text;
            credential.ServerPort = textBoxServerPort.Text;
            credential.DbFileVersionMust = m_DbFileVersionMust;
            

            if (credential.DbFileVersionMust)
            {
                if (comboBoxFileVersion.SelectedItem == null)
                    throw new ApplicationException("Please choose file version first.");
            }

            if (comboBoxFileVersion.SelectedItem != null)
                credential.DbFileVersion = (FileVersionPair)comboBoxFileVersion.SelectedItem;

            if (radioBtnOSAuth.Enabled)
                credential.OsInteAuth = radioBtnOSAuth.Checked;

            return credential;
        }

 
        #endregion

        #region Event Handlers

        private void FormConnConfig_Load(object sender, EventArgs e)
        {
            tabControl1.SelectedIndex = 0;
            m_SelectedPluginIndex = -1;
            comboBoxDbPlugins.SelectedIndex = -1;

            LoadDbPluginProviders();
            if (comboBoxDbPlugins.Items.Count > 0)
            {
                comboBoxDbPlugins.SelectedIndex = 0;
            }
        }


        private void buttonGoWizard_Click(object sender, EventArgs e)
        {
            string connectionSection = textBoxConnectionSection1.Text;
            string connectionString;
            string providerName;
            bool trySuccessful = ConnectionSectionBuilder.TryParseConnectionSection(
                connectionSection,
                out connectionString,
                out providerName);
            if (trySuccessful == false)
            {
                MessageBox.Show("Parse connection section failed.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }

            try
            {
                m_SelectedPlugin = m_PluginProvider.ChoosePlugin(providerName, connectionString);
                DbServerCredential credential = m_SelectedPlugin.CreateCredential(connectionString);

                var pluginNamePair = m_SelectedPlugin.PluginNamePair;
                object selectedItem = null;
                foreach (var item in comboBoxDbPlugins.Items)
                {

                    PluginNamePair tempPair = (PluginNamePair)item;
                    if (pluginNamePair.Equals(tempPair))
                        selectedItem = item;
                }

                //make sure invoke the comboBoxDbProviders_SelectedIndexChanged()
                comboBoxDbPlugins.SelectedItem = null;
                comboBoxDbPlugins.SelectedItem = selectedItem;
                InitUIByDbCredential(credential);

                tabControl1.SelectedIndex = 1;
            }
            catch
            {
                string messageFmt = "Db of ProviderName='{0}' is not implemented yet.";
                string message = string.Format(messageFmt, providerName);
                MessageBox.Show(message, "Info", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }


        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }



        private void btnTestConnection_Click(object sender, EventArgs e)
        {
            bool needTest = true;
            GenerateConnSection(needTest);
        }

        private void GenerateConnSection(bool needTest)
        {
            if (m_SelectedPlugin == null)
                return;

            DbServerCredential credential = null;
            try
            {
                credential = InitDbCredentialByUI();
            }
            catch (Exception ex)
            {
                string message = ex.Message;
                MessageBox.Show(message, "Info", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var connStrbuilder = m_SelectedPlugin.CreateConnectionStrBuilder(credential);
            var connectionString = connStrbuilder.ConnectionString;
            DbConnection connection = null;
            try
            {
                PluginNamePair pluginNamePair = m_SelectedPlugin.PluginNamePair;
                string connSection = ConnectionSectionBuilder.BuildConnectionSection(pluginNamePair.ProviderName, connectionString);
                textBoxConnectionSection2.Text = connSection;

                if (needTest)
                {
                    string connectionString2;
                    string providerName2;
                    var converable = ConnectionSectionBuilder.TryParseConnectionSection(connSection, out connectionString2, out providerName2);
                    if (converable)
                    {
                        connection = m_SelectedPlugin.CreateDbConnection(connectionString2);

                        connection.Open();
                        MessageBox.Show("Connect successfully.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else
                    {
                        string message = "Cannot convert connection section. Please check.";
                        MessageBox.Show(message, "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
            catch (Exception ex)
            {
                string message = "Connect failed." + Environment.NewLine + ex.Message;
                MessageBox.Show(message, "Info", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if (connection != null)
                    connection.Close();
            }
        }

        private void comboBoxDbPlugins_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxDbPlugins.SelectedIndex == m_SelectedPluginIndex)
                return;

            m_SelectedPluginIndex = comboBoxDbPlugins.SelectedIndex;
            if (m_SelectedPluginIndex < 0)
                return;

            PluginNamePair pluginNamePair = (PluginNamePair)comboBoxDbPlugins.SelectedItem;
            m_SelectedPlugin = m_PluginProvider.ChoosePlugin(pluginNamePair.DisplayName);

            string connectionString = string.Empty;
            DbServerCredential credential = m_SelectedPlugin.CreateCredential(connectionString);
            InitUIByDbCredential(credential);
        }

        #endregion

        public FormConnConfig()
        {
            InitializeComponent();
        }


        #region Public methods/properties

        public void SetInitialConnectionSection(string connectionSection)
        {
            textBoxConnectionSection1.Text = connectionSection;
        }

        public string GetFinalConnectionSection()
        {
            return textBoxConnectionSection2.Text;
        }

        #endregion

 

        private void btnGenerateConnection_Click(object sender, EventArgs e)
        {
            bool needTest = false;
            GenerateConnSection(needTest);
        }

   

    
    }
}
